Skip to content

Conversation

@dev-ant
Copy link
Contributor

@dev-ant dev-ant commented Jan 10, 2026

📋 상세 설명

  • 종합 통계 시스템 도입: 기존 단순 최저가(ItemDailyMinPrice) 추적을 대체하고, 아이템/서브카테고리/최상위 카테고리 3단계 통계를 계산하도록 구현됨.
    • 단순 최소가 추적에서 다양한 레벨과 기간(일별/주별) 통계로 확장됨.
  • 스케줄러 추가: 경매 기록 저장 이벤트 후 일간 통계, 매주 월요일 4시 주간 통계, 전일 통계 확정 스케줄러가 실행됨.
    • 자동화된 스케줄러로 통계 계산을 정기적으로 수행하도록 설계됨.
  • DB 및 서비스 구조 변경: JPA 엔티티, 리포지토리(네이티브 SQL 포함), 서비스, REST 컨트롤러, 테스트 코드 포함한 통합 구현.
    • 통계 기능을 완전히 새로 설계하면서 데이터베이스 마이그레이션과 API까지 반영됨.

📊 체크리스트

  • PR 제목이 형식에 맞나요 e.g. feat: PR을 등록한다
  • 코드가 테스트 되었나요 조회 API 개선 후 추가
  • 문서는 업데이트 되었나요 조회 API 개선 후 업데이트
  • 불필요한 코드를 제거했나요
  • 이슈와 라벨이 등록되었나요

📆 마감일

Close #81

@github-actions
Copy link

github-actions bot commented Jan 10, 2026

✅ 테스트 결과 for PR

Build: success

🧪 테스트 실행 with Gradle
📈 Coverage: -0.00%

📁 테스트 결과
📁 커버리지 보고서 (HTML)

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a comprehensive statistics aggregation system to replace the previous simple min-price tracking. It introduces daily and weekly statistics calculated across three levels (item, subcategory, and top category), with schedulers that run after auction history data is loaded. The implementation includes database migrations, JPA entities, repositories with native SQL queries, service layers, REST controllers, and corresponding tests.

Key Changes:

  • Adds daily statistics scheduler triggered by auction history save events
  • Adds weekly statistics scheduler (runs Mondays at 4 AM) and previous-day statistics finalization scheduler (runs daily at 00:10)
  • Replaces old ItemDailyMinPrice functionality with comprehensive multi-level statistics

Reviewed changes

Copilot reviewed 68 out of 73 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
V13__create_statistics_tables.sql Creates 6 new statistics tables (3 daily, 3 weekly) for item/subcategory/topcategory levels
application.yml Adds statistics.previous-day.cron configuration property
DailyStatisticsService.java Service handling current-day and previous-day statistics calculation
PreviousDayStatisticsScheduler.java Scheduler for finalizing previous day statistics at 00:10
WeeklyStatisticsScheduler.java Scheduler for weekly statistics aggregation on Mondays
*Repository.java Native SQL queries for upsert operations on statistics tables
AuctionHistorySavedEvent.java Event published after auction history save to trigger statistics update
OpenApiAuctionHistoryMapper.java Changed to convert UTC timestamps to KST by adding 9 hours
PageRequestDto.java Modified page calculation logic
docker-compose files Updated database configuration and removed min-price cron

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 43 to 44
FROM item_weekly_statistics iws
INNER JOIN auction_history ah ON iws.item_name = ah.item_name
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to TopCategoryWeeklyStatisticsRepository, joining with auction_history to get category mappings may result in incorrect or duplicate data. The same item_name can appear in auction_history with different sub_categories. Consider using a more reliable source for category relationships.

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +32
default Instant utcToKst(Instant utcTime) {
// API에서 받은 UTC 시간에 9시간을 더하여 KST로 변환
return utcTime != null ? utcTime.plus(9, ChronoUnit.HOURS) : null;
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mapper is converting UTC time to KST by adding 9 hours, but this assumes the API always returns UTC. The variable name and comment should clarify this assumption. Additionally, verify that the API actually returns UTC timestamps as this conversion could lead to incorrect data if the assumption is wrong.

Suggested change
default Instant utcToKst(Instant utcTime) {
// API에서 받은 UTC 시간에 9시간을 더하여 KST로 변환
return utcTime != null ? utcTime.plus(9, ChronoUnit.HOURS) : null;
default Instant utcToKst(Instant apiUtcInstant) {
// 외부 OpenAPI가 UTC 타임스탬프를 반환한다고 가정하고, KST(UTC+9)로 변환한다.
return apiUtcInstant != null ? apiUtcInstant.plus(9, ChronoUnit.HOURS) : null;

Copilot uses AI. Check for mistakes.
FROM subcategory_daily_statistics sds
INNER JOIN item_daily_statistics ids ON sds.item_sub_category = ids.item_sub_category
AND sds.date_auction_buy = ids.date_auction_buy
WHERE sds.date_auction_buy = DATE(NOW())
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SQL uses DATE(NOW()) which gets the current date but the intention is to process previous day statistics. This should be DATE(NOW()) - INTERVAL 1 DAY to correctly target the previous day's data, matching the other "upsertPreviousDayStatistics" methods.

Copilot uses AI. Check for mistakes.

public Pageable toPageable() {
int resolvedPage = this.page != null ? this.page - 1 : DEFAULT_PAGE;
int resolvedPage = this.page != null ? this.page - 1 : DEFAULT_PAGE - 1;
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The page calculation has been changed from "this.page - 1" to "this.page - 1" with no actual change to the logic, but DEFAULT_PAGE - 1 is used when page is null. This means when page is null, it becomes -1 (0 - 1), which is an invalid page number. The correct logic should keep the original "DEFAULT_PAGE" without subtracting 1.

Copilot uses AI. Check for mistakes.
private final WeeklyStatisticsService weeklyStatisticsService;

/** 매주 월요일 새벽 주간 통계 계산 및 저장 (전주 데이터 집계) 기본 cron: 매주 월요일 새벽 4시 (변경 가능) */
@Scheduled(cron = "${statistics.weekly.cron:5 0 4 * * MON}", zone = "Asia/Seoul")
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cron expression has an extra "5" prefix making it invalid. The correct format should be "0 0 4 * * MON" without the leading "5".

Copilot uses AI. Check for mistakes.
- "${SERVER_PORT}:${SERVER_PORT}"
env_file:
- .env
- .env:
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The YAML syntax is incorrect. There should not be a colon after ".env". It should be just ".env" without the trailing colon.

Suggested change
- .env:
- .env

Copilot uses AI. Check for mistakes.
Comment on lines +43 to +44
FROM subcategory_weekly_statistics sws
INNER JOIN auction_history ah ON sws.item_sub_category = ah.item_sub_category
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JOIN condition uses auction_history.item_top_category but this may lead to incorrect mappings since the same item_sub_category can belong to different top categories. Consider using a unique mapping or lookup table instead of relying on auction_history for category relationships.

Copilot uses AI. Check for mistakes.
Comment on lines +35 to +37
statistics:
daily:
cron: '0 0 3 * * *'
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The configuration property path has been changed from "statistics.daily.cron" to "statistics.previous-day.cron" but the test file still uses "statistics.daily.cron" at line 37. This inconsistency will cause the scheduler to not pick up the test configuration correctly.

Copilot uses AI. Check for mistakes.
# === External API Configuration ===
NEXON_OPEN_API_KEY: ${NEXON_OPEN_API_KEY}
AUCTION_HISTORY_DELAY_MS: ${AUCTION_HISTORY_DELAY_MS:-1000}
AUCTION_HISTORY_CRON: "${AUCTION_HISTORY_CRON:-0 0 * * * *}"
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing the environment variable STATISTICS_PREVIOUS_DAY_CRON in the docker-compose configuration. The application.yml uses this property with a default value, but for consistency and explicit configuration in production, it should be added to the environment variables list.

Suggested change
AUCTION_HISTORY_CRON: "${AUCTION_HISTORY_CRON:-0 0 * * * *}"
AUCTION_HISTORY_CRON: "${AUCTION_HISTORY_CRON:-0 0 * * * *}"
STATISTICS_PREVIOUS_DAY_CRON: "${STATISTICS_PREVIOUS_DAY_CRON:-0 0 * * * *}"

Copilot uses AI. Check for mistakes.
@dev-ant dev-ant merged commit 966f1c7 into dev Jan 13, 2026
1 of 2 checks passed
@dev-ant dev-ant deleted the feat/auction-history-statics branch January 13, 2026 04:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

경매장 거래 내역 통계 저장 스케쥴러 추가

2 participants